package com.zcy.gift.service.impl;

import com.zcy.gift.constant.GiftConstant;
import com.zcy.gift.domain.GoodsSpu;
import com.zcy.gift.dto.SpuOnsaleDto;
import com.zcy.gift.exception.ResponseCode;
import com.zcy.gift.exception.RonghuaAssert;
import com.zcy.gift.mapper.GoodsSpuMapper;
import com.zcy.gift.service.IGoodsSpuService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zcy.gift.util.VelocityUtils;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * spu表 服务实现类
 * </p>
 *
 * @author zcy
 * @since 2024-02-02
 */
@Service
public class GoodsSpuServiceImpl extends ServiceImpl<GoodsSpuMapper, GoodsSpu> implements IGoodsSpuService {


    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private GoodsSpuMapper goodsSpuMapper;

    @Value("${gift.goodsSpu.targetFilePath}")
    private String templateFilePath;

    @Value("${gift.goodsSpu.templateFilePath}")
    private String targetFilePath;


    @Override
    public String onSale(List<Long> ids) {
        // 参数校验 ids 不能为空
        RonghuaAssert.isNotNull(ids, ResponseCode.RESPONSE_CODE_40013);
        // 商品必须审核通过
//        List<GoodsSpu> goodsSpus = super.selectBatchIds(ids).stream().filter(goods -> Objects.equals(goods.getState(), GiftConstant.GIFT_SALE_AUDIT_PASS)).collect(Collectors.toList());
        List<GoodsSpu> goodsSpus = super.selectBatchIds(ids).stream().filter(goods -> !Objects.equals(goods.getState(), GiftConstant.GIFT_SALE_ONSALE)).collect(Collectors.toList());
        RonghuaAssert.isNotNull(goodsSpus, ResponseCode.RESPONSE_CODE_40015);
        // 商品成功上架xxx条，失败xxx条
        String msg = "商品共" + ids.size() + "条，成功上架" + goodsSpus.size() + "条，失败" + (ids.size() - goodsSpus.size()) + "条";
        //2发送事务消息到rocketmq
        //在下rocketmq发送事务消息结束后，在本地事务中执行：修改数据库操作
        List<SpuOnsaleDto> spuOnsaleDtos = new ArrayList<>();
        for (GoodsSpu spu : goodsSpus) {
            SpuOnsaleDto saleDto = new SpuOnsaleDto();
            saleDto.setId(spu.getId());
            saleDto.setSpuId(spu.getId());
            saleDto.setCover(spu.getCover());
            saleDto.setName(spu.getGoodsName());
            saleDto.setTenantId(spu.getTenantId());
            saleDto.setTenantName(spu.getTenantName());
            saleDto.setOnsaleTime(new Date());
            saleDto.setTypeId(spu.getCategoryId());
            saleDto.setTypeName("口红");
            saleDto.setBrandId(spu.getBrandId());
            saleDto.setBrandName("香奈儿");
            // 无
            saleDto.setCommentCount(0);
            saleDto.setSaleCount(0);
            saleDto.setSkuProperties("");
            saleDto.setSkuProperties("");
            //
            saleDto.setMaxPrice(spu.getHighPrice());
            saleDto.setMinPrice(spu.getLowPrice());

            spuOnsaleDtos.add(saleDto);
        }
        Message<List<SpuOnsaleDto>> message = MessageBuilder.withPayload(spuOnsaleDtos).build();
        TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction(GiftConstant.GIFT_ONSALE_TX_PRODUCER_GROUP,
                GiftConstant.GIFT_ONSALE_TX_TOPIC + ":" + GiftConstant.GIFT_ONSALE_TX_TAG,
                message, null
        );
        System.out.println(sendResult);

        // 3 新增静态页面
        for (GoodsSpu spus : goodsSpus) {
            String path = this.targetFilePath+"\\"+spus.getId()+".html";
            VelocityUtils.staticByTemplate(spus, this.templateFilePath, path);
        }
        return msg;
    }

    @Override
    public void offSale(List<Long> ids) {
        // 参数校验 ids 不能为空
        RonghuaAssert.isNotNull(ids, ResponseCode.RESPONSE_CODE_40014);

//        goodsSpuMapper.offsale(ids);

        // 发送消息队列
        Message<List<Long>> message = MessageBuilder.withPayload(ids).build();
        TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction(GiftConstant.GIFT_OFFSALE_TX_PRODUCER_GROUP,
                GiftConstant.GIFT_OFFSALE_TX_TOPIC + ":" + GiftConstant.GIFT_OFFSALE_TX_TAG,
                message, null
        );
        // 3 删除es中的数据  删除静态页面文件
        for (Long id : ids) {
            String path = this.targetFilePath+"\\"+id+".html";
            File file = new File(path);
            if(file.exists()){
                file.delete();
            }
        }

    }

    /**
     * 礼物上架执行本地事务
     * @param dtos
     */
    @Override
    @Transactional
    public void spuOnsaleExecuteLocalTransaction(List<SpuOnsaleDto> dtos) {
        List<Long> ids = dtos.stream().map(SpuOnsaleDto::getId).collect(Collectors.toList());
        // 1 修改数据库状态
        goodsSpuMapper.onsale(ids);
        // 2 添加操作日志 TODO 暂无操作日志表



    }

    @Override
    public Boolean spuOnsaleCheckLocalTransaction(List<SpuOnsaleDto> dtos) {
        List<Long> ids = dtos.stream().map(SpuOnsaleDto::getId).collect(Collectors.toList());

        List<GoodsSpu> goodsSpus = super.selectBatchIds(ids);

        goodsSpus = goodsSpus.stream().filter(x -> Objects.equals(x.getState(), GiftConstant.GIFT_SALE_ONSALE)).collect(Collectors.toList());

        return !goodsSpus.isEmpty();
    }

    /**
     * 礼物下架执行本地事务
     * @param ids
     */
    @Override
    @Transactional
    public void spuOffsaleExecuteLocalTransaction(List<Long> ids) {
        // 修改数据库状态
        goodsSpuMapper.offsale(ids);

        // 添加操作日志 TODO 暂无操作日志表
    }

    /**
     * 回调检查礼物下架本地事务执行结果
     * @param ids
     * @return
     */
    @Override
    public Boolean spuOffsaleCheckLocalTransaction(List<Long> ids) {
        List<GoodsSpu> goodsSpus = super.selectBatchIds(ids);
        List<GoodsSpu> offsaleGoods = goodsSpus.stream().filter(x -> Objects.equals(x.getState(), GiftConstant.GIFT_SALE_OFFSALE)).collect(Collectors.toList());
        return !offsaleGoods.isEmpty();
    }
}
